import { _decorator, Component, Node, Prefab, instantiate, Label, Button, Vec3, SpriteFrame, Sprite, Director, TweenSystem, tween, Tween, director } from 'cc';
const { ccclass, property } = _decorator;

// 消除块类型（对应4种颜色）
enum BlockType { Red, Blue, Green, Yellow }

@ccclass('Grid')
export class Grid extends Component {
    // 需手动关联的素材（在属性检查器中设置）
    @property(Prefab) blockPrefab: Prefab = null; // 关联Block预制体
    @property(Label) scoreLabel: Label = null; // 关联分数文字
    @property(Label) stepLabel: Label = null; // 关联步数文字
    @property(Button) restartBtn: Button = null; // 关联重新开始按钮
    @property([SpriteFrame]) blockSpriteFrames: SpriteFrame[] = []; // 4种颜色消除块图片
    
    // 新增：历史分数相关属性
    @property(Label) historyLabel: Label = null; // 关联历史分数文字
    @property(Button) showHistoryBtn: Button = null; // 关联显示历史分数按钮
    @property(Node) historyPanel: Node = null; // 关联历史分数面板
    @property(Button) closeHistoryBtn: Button = null; // 关联关闭历史面板按钮

    // 服务器配置
    private readonly API_BASE = 'http://112.124.99.204:3000';
    private userId: number = 0;

    // 游戏参数（新手可修改数字）
    @property({ tooltip: "网格行数（建议8）" }) row = 8;
    @property({ tooltip: "网格列数（建议8）" }) col = 8;
    @property({ tooltip: "每个消除块大小（建议50，可增大减少拥挤）" }) blockSize = 50;
    @property({ tooltip: "总步数（建议20）" }) totalSteps = 20;
    @property({ tooltip: "消除一个块的得分（建议10）" }) scorePerBlock = 10;
    @property({ tooltip: "选中时的缩放倍数（建议1.2）" }) selectedScale = 1.2; // 选中时的缩放倍数

    // 内部变量
    private grid: (Node | null)[][] = []; // 存储消除块节点
    private score = 0; // 当前分数
    private usedSteps = 0; // 已用步数
    private selectedBlock: Node | null = null; // 选中的消除块
    private isSwapping = false; // 是否正在交换（防重复点击）
    private swappedBlocks: { blockA: Node | null, blockB: Node | null } = { blockA: null, blockB: null }; // 记录交换的两个块，用于回退

    onLoad() {
         // 获取用户ID（用于提交分数）
        const savedUserId = localStorage.getItem('userId');
        if (savedUserId) {
        this.userId = parseInt(savedUserId);
        console.log('当前用户ID:', this.userId);
        } else {
        console.log('用户未登录，分数将不会保存');
        // 可以在这里添加跳回登录界面的逻辑，或者只是提示
        }

        // 绑定重新开始按钮点击事件
        if (this.restartBtn) {
            this.restartBtn.node.on(Button.EventType.CLICK, this.restartGame, this);
        } else {
            console.error("restartBtn is not assigned in property inspector!");
        }
        
        // 新增：绑定历史分数按钮事件
        if (this.showHistoryBtn) {
            this.showHistoryBtn.node.on(Button.EventType.CLICK, this.showHistoryScores, this);
        }
        
        // 新增：绑定关闭历史面板按钮事件
        if (this.closeHistoryBtn) {
            this.closeHistoryBtn.node.on(Button.EventType.CLICK, this.closeHistoryPanel, this);
        }
        
        // 新增：初始化隐藏历史面板
        if (this.historyPanel) {
            this.historyPanel.active = false;
        }

        // 启用Tween系统，用于动画效果
        const tweenSystem = director.getSystem(TweenSystem);
        if (tweenSystem) {
            tweenSystem.enabled = true;
        }
    }

    start() {
        // 生成初始网格
        this.initGrid();
    }

    // 新增：显示历史分数
    private async showHistoryScores() {
        if (!this.userId) {
            if (this.historyLabel) {
                this.historyLabel.string = '请先登录查看历史成绩';
            }
            return;
        }

        try {
            const response = await fetch(`${this.API_BASE}/api/user-scores?user_id=${this.userId}`);
            const result = await response.json();
            
            if (result.success && result.scores && result.scores.length > 0) {
                this.displayHistoryScores(result.scores);
            } else {
                this.displayNoScores();
            }
        } catch (error) {
            console.log('获取历史成绩失败:', error);
            if (this.historyLabel) {
                this.historyLabel.string = '获取历史成绩失败';
            }
        }
        
        // 显示历史面板
        if (this.historyPanel) {
            this.historyPanel.active = true;
        }
    }

    // 新增：格式化显示历史分数
    private displayHistoryScores(scores: any[]) {
        let historyText = '📊 历史成绩\n';
        historyText += '----------------\n';
        
        scores.forEach((score, index) => {
            const date = new Date(score.play_time).toLocaleDateString();
            historyText += `${index + 1}. 分数: ${score.score} | 时间: ${date}\n`;
        });

        if (this.historyLabel) {
            this.historyLabel.string = historyText;
        }
    }

    // 新增：显示无成绩提示
    private displayNoScores() {
        if (this.historyLabel) {
            this.historyLabel.string = '暂无历史成绩，开始游戏吧！';
        }
    }

    // 新增：关闭历史面板
    private closeHistoryPanel() {
        if (this.historyPanel) {
            this.historyPanel.active = false;
        }
    }

    // 在游戏结束时提交分数到服务器
    private async submitScore() {
        if (!this.userId) {
            console.log('用户未登录，分数未保存');
            return;
        }

        try {
            const response = await fetch(`${this.API_BASE}/api/submit-score`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    user_id: this.userId,
                    score: this.score,
                    level: 1
                })
            });

            const result = await response.json();
            if (result.success) {
                console.log('分数提交成功');
                // 提交成功后自动显示历史成绩
                setTimeout(() => {
                    this.showHistoryScores();
                }, 500);
            } else {
                console.log('分数提交失败:', result.message);
            }
        } catch (error) {
            console.log('网络错误，分数未保存:', error);
        }
    }

    // 重新开始游戏（重置所有数据）
    restartGame = () => {
        if (this.row <= 0 || this.col <= 0) {
            console.error("row or col is invalid!");
            return;
        }
        // 删除旧消除块
        for (let r = 0; r < this.row; r++) {
            for (let c = 0; c < this.col; c++) {
                if (this.grid[r] && this.grid[r][c]) {
                    this.grid[r][c].destroy();
                }
            }
        }
        // 重置所有状态
        this.score = 0;
        this.usedSteps = 0;
        this.selectedBlock = null;
        this.isSwapping = false;
        this.swappedBlocks = { blockA: null, blockB: null };
        // 更新UI
        if (this.scoreLabel) this.scoreLabel.string = `分数：${this.score}`;
        if (this.stepLabel) this.stepLabel.string = `步数：${this.totalSteps - this.usedSteps}`;
        // 重新生成网格
        this.initGrid();
        
        // 关闭历史面板
        this.closeHistoryPanel();
    }

    // 生成初始网格（8x8消除块）
    initGrid() {
        this.grid = Array.from({ length: this.row }, () => Array(this.col).fill(null));
        const gridWidth = this.col * this.blockSize;
        const gridHeight = this.row * this.blockSize;
        const startX = -gridWidth / 2 + this.blockSize / 2;
        const startY = gridHeight / 2 - this.blockSize / 2;

        for (let r = 0; r < this.row; r++) {
            for (let c = 0; c < this.col; c++) {
                if (!this.blockPrefab) {
                    console.error("blockPrefab is not assigned!");
                    return;
                }
                const block = instantiate(this.blockPrefab);
                if (!block) {
                    console.error("Failed to instantiate block at row", r, "col", c);
                    continue;
                }
                this.node.addChild(block);
                this.grid[r][c] = block;

                // 设置位置
                const posX = startX + c * this.blockSize;
                const posY = startY - r * this.blockSize;
                block.setPosition(posX, posY);

                // 随机颜色
                const blockType = Math.floor(Math.random() * 4);
                const sprite = block.getComponent(Sprite);
                if (sprite && this.blockSpriteFrames.length > blockType) {
                    sprite.spriteFrame = this.blockSpriteFrames[blockType];
                }

                // 绑定点击事件
                block.on(Node.EventType.TOUCH_END, () => this.onBlockClick(block, r, c), this);
                block.userData = { row: r, col: c, type: blockType };
            }
        }

        // 确保初始无匹配（避免开局直接消除）
        let matchedBlocks = this.checkMatch();
        while (matchedBlocks.length > 0) {
            this.resetGridBlocks();
            matchedBlocks = this.checkMatch();
        }
    }

    // 重置网格颜色（初始有匹配时调用）
    resetGridBlocks() {
        for (let r = 0; r < this.row; r++) {
            for (let c = 0; c < this.col; c++) {
                const block = this.grid[r][c];
                if (block) {
                    const blockType = Math.floor(Math.random() * 4);
                    const sprite = block.getComponent(Sprite);
                    if (sprite && this.blockSpriteFrames.length > blockType) {
                        sprite.spriteFrame = this.blockSpriteFrames[blockType];
                    }
                    block.userData = { row: r, col: c, type: blockType };
                }
            }
        }
    }

    // 选中块时的放大效果
    selectBlock(block: Node) {
        // 停止所有现有动画
        Tween.stopAllByTarget(block);
        
        // 创建放大动画
        tween(block)
            .to(0.2, { scale: new Vec3(this.selectedScale, this.selectedScale, 1) })
            .start();
    }

    // 取消选中块时的恢复效果
    deselectBlock(block: Node) {
        // 停止所有现有动画
        Tween.stopAllByTarget(block);
        
        // 创建恢复动画
        tween(block)
            .to(0.2, { scale: new Vec3(1, 1, 1) })
            .start();
    }

    // 检查两个方块是否相邻
    isAdjacentBlocks(blockA: Node, blockB: Node): boolean {
        const dataA = blockA.userData as { row: number, col: number, type: BlockType };
        const dataB = blockB.userData as { row: number, col: number, type: BlockType };
        
        if (!dataA || !dataB) return false;
        
        // 检查是否在同一行且列相邻，或者在同一列且行相邻
        const rowDiff = Math.abs(dataA.row - dataB.row);
        const colDiff = Math.abs(dataA.col - dataB.col);
        
        return (rowDiff === 1 && colDiff === 0) || (rowDiff === 0 && colDiff === 1);
    }

    // 消除块点击事件（选中/交换逻辑）
    onBlockClick(block: Node, r: number, c: number) {
        if (this.isSwapping || this.usedSteps >= this.totalSteps) {
            return;
        }

        if (!this.selectedBlock) {
            // 无选中 → 选中当前块
            this.selectedBlock = block;
            this.selectBlock(block);
        } else if (this.selectedBlock === block) {
            // 选中自身 → 取消选中
            this.deselectBlock(block);
            this.selectedBlock = null;
        } else {
            // 选中其他块 → 判断相邻性
            if (this.isAdjacentBlocks(this.selectedBlock, block)) {
                // 记录要交换的两个块（用于后续回退）
                this.swappedBlocks = { blockA: this.selectedBlock, blockB: block };
                // 取消之前选中的块
                this.deselectBlock(this.selectedBlock);
                this.swapBlocks(this.selectedBlock, block);
            } else {
                // 不相邻 → 切换选中
                this.deselectBlock(this.selectedBlock);
                this.selectedBlock = block;
                this.selectBlock(block);
            }
        }
    }

    // 交换两个消除块（带动画）
    swapBlocks(blockA: Node, blockB: Node) {
        this.isSwapping = true;
        
        const dataA = blockA.userData as { row: number, col: number, type: BlockType };
        const dataB = blockB.userData as { row: number, col: number, type: BlockType };
        
        if (!dataA || !dataB) {
            this.isSwapping = false;
            return;
        }
        
        // 记录交换前的位置（用于动画回退）
        const posA = blockA.position.clone();
        const posB = blockB.position.clone();
        
        // 交换网格中的位置
        this.grid[dataA.row][dataA.col] = blockB;
        this.grid[dataB.row][dataB.col] = blockA;
        
        // 更新块的数据
        blockA.userData = { row: dataB.row, col: dataB.col, type: dataA.type };
        blockB.userData = { row: dataA.row, col: dataA.col, type: dataB.type };
        
        // 执行交换动画，动画结束后检查匹配
        tween(blockA)
            .to(0.3, { position: posB })
            .parallel(
                tween(blockB).to(0.3, { position: posA })
            )
            .call(() => {
                this.checkAndHandleMatches();
            })
            .start();
    }

    // 检查并处理匹配（核心：无匹配则回退）
    checkAndHandleMatches() {
        const matchedBlocks = this.checkMatch();
        if (matchedBlocks.length > 0) {
            // 有匹配 → 执行消除逻辑
            this.usedSteps++;
            if (this.stepLabel) this.stepLabel.string = `步数：${this.totalSteps - this.usedSteps}`;
            this.eliminateBlocks(matchedBlocks);
        } else {
            // 无匹配 → 交换回原位置
            this.swapBack();
        }
        
        // 重置选中状态
        this.selectedBlock = null;
    }

    // 交换回原位置（无匹配时触发，带动画）
    swapBack() {
        const { blockA, blockB } = this.swappedBlocks;
        if (!blockA || !blockB) {
            this.isSwapping = false;
            return;
        }
        
        const dataA = blockA.userData as { row: number, col: number, type: BlockType };
        const dataB = blockB.userData as { row: number, col: number, type: BlockType };
        
        if (!dataA || !dataB) {
            this.isSwapping = false;
            return;
        }
        
        // 记录回退前的位置（动画用）
        const posA = blockA.position.clone();
        const posB = blockB.position.clone();
        
        // 交换回网格中的原始位置
        this.grid[dataA.row][dataA.col] = blockB;
        this.grid[dataB.row][dataB.col] = blockA;
        
        // 更新回块的原始数据
        blockA.userData = { row: dataB.row, col: dataB.col, type: dataA.type };
        blockB.userData = { row: dataA.row, col: dataA.col, type: dataB.type };
        
        // 执行回退动画，结束后解锁交换状态
        tween(blockA)
            .to(0.3, { position: posB })
            .parallel(
                tween(blockB).to(0.3, { position: posA })
            )
            .call(() => {
                this.isSwapping = false;
                this.swappedBlocks = { blockA: null, blockB: null }; // 重置交换记录
            })
            .start();
    }

    // 检测所有匹配的消除块（横向/纵向3个及以上）
    checkMatch(): Node[] {
        const matchedBlocks = new Set<Node>();

        // 横向匹配检测（3个及以上连续同色）
        for (let r = 0; r < this.row; r++) {
            if (!this.grid[r]) continue;
            for (let c = 0; c < this.col - 2; c++) {
                const block1 = this.grid[r][c];
                const block2 = this.grid[r][c + 1];
                const block3 = this.grid[r][c + 2];
                if (!block1 || !block2 || !block3) continue;

                const type1 = (block1.userData as { type: BlockType }).type;
                const type2 = (block2.userData as { type: BlockType }).type;
                const type3 = (block3.userData as { type: BlockType }).type;

                if (type1 === type2 && type2 === type3) {
                    matchedBlocks.add(block1);
                    matchedBlocks.add(block2);
                    matchedBlocks.add(block3);
                    // 检测更长连续（如4、5个同色）
                    let extendC = c + 3;
                    while (extendC < this.col && this.grid[r] && this.grid[r][extendC] && (this.grid[r][extendC].userData as { type: BlockType }).type === type1) {
                        matchedBlocks.add(this.grid[r][extendC]);
                        extendC++;
                    }
                }
            }
        }

        // 纵向匹配检测（3个及以上连续同色）
        for (let c = 0; c < this.col; c++) {
            for (let r = 0; r < this.row - 2; r++) {
                const block1 = this.grid[r] ? this.grid[r][c] : null;
                const block2 = this.grid[r + 1] ? this.grid[r + 1][c] : null;
                const block3 = this.grid[r + 2] ? this.grid[r + 2][c] : null;
                if (!block1 || !block2 || !block3) continue;

                const type1 = (block1.userData as { type: BlockType }).type;
                const type2 = (block2.userData as { type: BlockType }).type;
                const type3 = (block3.userData as { type: BlockType }).type;

                if (type1 === type2 && type2 === type3) {
                    matchedBlocks.add(block1);
                    matchedBlocks.add(block2);
                    matchedBlocks.add(block3);
                    // 检测更长连续
                    let extendR = r + 3;
                    while (extendR < this.row && this.grid[extendR] && this.grid[extendR][c] && (this.grid[extendR][c].userData as { type: BlockType }).type === type1) {
                        matchedBlocks.add(this.grid[extendR][c]);
                        extendR++;
                    }
                }
            }
        }

        return Array.from(matchedBlocks);
    }

    // 消除匹配块（带动画+得分）
    eliminateBlocks(matchedBlocks: Node[]) {
        // 标记需要消除的块位置
        const positionsToRemove: { row: number, col: number }[] = [];
        matchedBlocks.forEach(block => {
            const data = block.userData as { row: number, col: number, type: BlockType };
            positionsToRemove.push({ row: data.row, col: data.col });
            
            // 消除动画：缩小至消失后销毁
            tween(block)
                .to(0.1, { scale: new Vec3(0, 0, 1) })
                .call(() => {
                    block.destroy();
                    this.grid[data.row][data.col] = null; // 标记网格位置为空
                })
                .start();
        });

        // 更新得分UI
        this.score += matchedBlocks.length * this.scorePerBlock;
        if (this.scoreLabel) this.scoreLabel.string = `分数：${this.score}`;

        // 延迟补块（等待消除动画完成）
        setTimeout(() => {
            this.fillEmptySpaces();
            
            // 检测连锁消除
            const newMatched = this.checkMatch();
            if (newMatched.length > 0) {
                this.eliminateBlocks(newMatched);
            } else {
                this.isSwapping = false;
                this.swappedBlocks = { blockA: null, blockB: null };

                // 检查游戏是否结束，如果结束则提交分数
                if (this.usedSteps >= this.totalSteps) {
                    this.submitScore(); // 游戏结束时提交分数
                    alert(`游戏结束！最终得分: ${this.score}`);
                }
            }
        }, 300);
    }

    // 填充空缺（正常补块逻辑）
    fillEmptySpaces() {
        const gridWidth = this.col * this.blockSize;
        const gridHeight = this.row * this.blockSize;
        const startX = -gridWidth / 2 + this.blockSize / 2;
        const startY = gridHeight / 2 - this.blockSize / 2;

        // 对每一列进行处理
        for (let c = 0; c < this.col; c++) {
            // 计算每列中有多少空位
            let emptyCount = 0;
            
            // 从底部向上遍历，移动方块填补空位
            for (let r = this.row - 1; r >= 0; r--) {
                if (this.grid[r][c] === null) {
                    emptyCount++;
                } else if (emptyCount > 0) {
                    // 移动方块到空位
                    const block = this.grid[r][c];
                    if (block) {
                        const newRow = r + emptyCount;
                        this.grid[newRow][c] = block;
                        this.grid[r][c] = null;
                        
                        // 更新块的行信息
                        block.userData = { 
                            row: newRow, 
                            col: c, 
                            type: (block.userData as { type: BlockType }).type 
                        };
                        
                        // 更新位置（带动画）
                        const posY = startY - newRow * this.blockSize;
                        tween(block)
                            .to(0.3, { position: new Vec3(block.position.x, posY, 0) })
                            .start();
                    }
                }
            }
            
            // 在顶部生成新方块填补剩余空位
            for (let r = 0; r < emptyCount; r++) {
                if (!this.blockPrefab) {
                    console.error("blockPrefab is not assigned!");
                    return;
                }
                
                const block = instantiate(this.blockPrefab);
                if (!block) {
                    console.error("Failed to instantiate block at row", r, "col", c);
                    continue;
                }
                
                this.node.addChild(block);
                this.grid[r][c] = block;
                
                // 设置初始位置（在屏幕上方）
                const posX = startX + c * this.blockSize;
                const initialPosY = startY + this.blockSize * (emptyCount - r); // 上方位置，错开生成
                block.setPosition(posX, initialPosY);
                
                // 设置目标位置
                const targetPosY = startY - r * this.blockSize;
                
                // 随机颜色
                const blockType = Math.floor(Math.random() * 4);
                const sprite = block.getComponent(Sprite);
                if (sprite && this.blockSpriteFrames.length > blockType) {
                    sprite.spriteFrame = this.blockSpriteFrames[blockType];
                }
                
                // 绑定点击事件
                block.on(Node.EventType.TOUCH_END, () => this.onBlockClick(block, r, c), this);
                block.userData = { row: r, col: c, type: blockType };
                
                // 添加下落动画
                tween(block)
                    .to(0.3, { position: new Vec3(posX, targetPosY, 0) })
                    .start();
            }
        }
    }
}